package com.example.teaching_server.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

/**
 * 学期数据传输对象
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "学期信息")
public class TermDTO {

    @NotNull(message = "学期ID不能为空")
    @Positive(message = "学期ID必须是正整数")
    @Schema(description = "学期唯一标识", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
    private Long termId;

    @NotBlank(message = "学期名称不能为空")
    @Size(max = 50, message = "学期名稱长度不能超过50个字符")
    @Schema(description = "学期名称", example = "2024年春季学期", requiredMode = Schema.RequiredMode.REQUIRED)
    private String termName;

    @NotNull(message = "开始日期不能为空")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Schema(description = "学期开始日期", example = "2024-03-01", requiredMode = Schema.RequiredMode.REQUIRED)
    private LocalDate startDate;

    @NotNull(message = "结束日期不能为空")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Schema(description = "学期结束日期", example = "2024-07-15", requiredMode = Schema.RequiredMode.REQUIRED)
    private LocalDate endDate;

    @NotNull(message = "是否为当前学期不能为空")
    @Schema(description = "是否为当前学期", example = "true", requiredMode = Schema.RequiredMode.REQUIRED)
    private Boolean isCurrent;

    @Schema(description = "学期状态", example = "ONGOING", allowableValues = {"UPCOMING", "ONGOING", "COMPLETED"})
    private String status;

    @Schema(description = "学期代码", example = "2024-SPRING")
    private String termCode;

    @Schema(description = "学期描述", example = "2024学年春季学期")
    private String description;

    @Schema(description = "是否启用", example = "true")
    @Builder.Default
    private Boolean enabled = true;

    /**
     * 前端显示用格式化的日期
     */
    @Schema(description = "格式化日期范围", accessMode = Schema.AccessMode.READ_ONLY)
    public String getFormattedPeriod() {
        if (startDate == null || endDate == null) {
            return "日期未设置";
        }
        return startDate.toString() + " 至 " + endDate.toString();
    }

    /**
     * 获取学期总周数
     */
    @Schema(description = "学期总周数", accessMode = Schema.AccessMode.READ_ONLY)
    public Long getTotalWeeks() {
        if (startDate == null || endDate == null) {
            return 0L;
        }
        return ChronoUnit.WEEKS.between(startDate, endDate) + 1;
    }

    /**
     * 获取已过周数
     */
    @Schema(description = "已过周数", accessMode = Schema.AccessMode.READ_ONLY)
    public Long getWeeksPassed() {
        if (startDate == null || endDate == null) {
            return 0L;
        }
        LocalDate today = LocalDate.now();
        if (today.isBefore(startDate)) {
            return 0L;
        }
        if (today.isAfter(endDate)) {
            return getTotalWeeks();
        }
        return ChronoUnit.WEEKS.between(startDate, today) + 1;
    }

    /**
     * 获取剩余周数
     */
    @Schema(description = "剩余周数", accessMode = Schema.AccessMode.READ_ONLY)
    public Long getWeeksRemaining() {
        return getTotalWeeks() - getWeeksPassed();
    }

    /**
     * 获取进度百分比
     */
    @Schema(description = "学期进度百分比", accessMode = Schema.AccessMode.READ_ONLY)
    public Double getProgressPercentage() {
        Long totalWeeks = getTotalWeeks();
        if (totalWeeks == 0) {
            return 0.0;
        }
        return (getWeeksPassed() * 100.0) / totalWeeks;
    }

    /**
     * 判断学期是否已开始
     */
    @Schema(description = "学期是否已开始", accessMode = Schema.AccessMode.READ_ONLY)
    public boolean isStarted() {
        if (startDate == null) return false;
        return !LocalDate.now().isBefore(startDate);
    }

    /**
     * 判断学期是否已结束
     */
    @Schema(description = "学期是否已结束", accessMode = Schema.AccessMode.READ_ONLY)
    public boolean isEnded() {
        if (endDate == null) return false;
        return LocalDate.now().isAfter(endDate);
    }

    /**
     * 判断学期是否正在进行中
     */
    @Schema(description = "学期是否正在进行中", accessMode = Schema.AccessMode.READ_ONLY)
    public boolean isOngoing() {
        return isStarted() && !isEnded();
    }

    /**
     * 获取状态文本
     */
    @Schema(description = "状态文本", accessMode = Schema.AccessMode.READ_ONLY)
    public String getStatusText() {
        if (isEnded()) return "已结束";
        if (isOngoing()) return "进行中";
        return "未开始";
    }

    /**
     * 构建基础学期信息
     */
    public static TermDTO basic(Long termId, String termName, LocalDate startDate, LocalDate endDate, Boolean isCurrent) {
        return TermDTO.builder()
                .termId(termId)
                .termName(termName)
                .startDate(startDate)
                .endDate(endDate)
                .isCurrent(isCurrent)
                .enabled(true)
                .build();
    }

    /**
     * 验证学期日期是否有效
     */
    @Schema(description = "学期日期是否有效", accessMode = Schema.AccessMode.READ_ONLY)
    public boolean isValidDateRange() {
        return startDate != null && endDate != null && !endDate.isBefore(startDate);
    }
}
